package com.example.myapplication;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.ImageDecoder;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.example.myapplication.adapter.ChatInfo;
import com.qiniu.android.common.Zone;
import com.qiniu.android.http.ResponseInfo;
import com.qiniu.android.storage.Configuration;
import com.qiniu.android.storage.UpCompletionHandler;
import com.qiniu.android.storage.UploadManager;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class BaseActivity extends AppCompatActivity {

    protected static final String TAG = "testlog";
    protected UploadManager uploadManager = null;
    public static Toast toast = null;
    // 七牛云上传token
    protected String uploadToken = null;

//    public BaseActivity() {
//        BaseActivity.toast = initToast();
//    }

    protected UploadManager getUploadManager() {
        if (BaseActivity.this.uploadManager == null) {
            Configuration config = new Configuration.Builder()
                    .connectTimeout(10)           // 链接超时。默认10秒
                    .responseTimeout(60)          // 服务器响应超时。默认60秒
                    .build();
            // 重用uploadManager。一般地，只需要创建一个uploadManager对象
            //配置3个线程数并发上传；不配置默认为3，只针对file.size>4M生效。线程数建议不超过5，上传速度主要取决于上行带宽，带宽很小的情况单线程和多线程没有区别
            BaseActivity.this.uploadManager = new UploadManager(config, 3);
        }
        return BaseActivity.this.uploadManager;
    }

    protected String getAuthToken() {
        return "VNS99znpYpO-bC5BfD6LUWndPZiLj0tOcvYlr0-F:QdXZoQWF806bwvxgMRCAXR4fTio=:eyJzY29wZSI6ImhlbGxvd2ViIiwiZGVhZGxpbmUiOjE1OTE4NzMzNTN9";
    }

    protected Toast initToast() {
        if (BaseActivity.this.toast == null) {
            BaseActivity.this.toast = Toast.makeText(BaseActivity.this, "", Toast.LENGTH_SHORT);
        }
        return BaseActivity.this.toast;
    }

    // 上传七牛云

    String real_key = null;

    // 上传类型：
    enum UPLOAD_TYPE {
        RECORD,     // 录音
        IMAGE       // 图片
    }

    protected void upload() {
        upload(soundPath, soundName, UPLOAD_TYPE.RECORD);
    }

    protected void upload(String path, String key, final UPLOAD_TYPE uploadType) {
        Log.d(TAG, "upload: path:" + path + ",key:" + key);
        final String token = getUploadToken();
        UploadManager uploadManager = BaseActivity.this.getUploadManager();
        uploadManager.put(path, key, token,
                new UpCompletionHandler() {
                    @Override
                    public void complete(String key, ResponseInfo info, JSONObject res) {
                        //res包含hash、key等信息，具体字段取决于上传策略的设置
                        String log = "";
                        //如果失败，这里可以把info信息上报自己的服务器，便于后面分析上传错误原因
                        log += key + ",\r\n " + info + ",\r\n " + res;
                        if (info.isOK()) {
                            log += "upload success";
                            try {
                                if (res != null && res.has("key")) {
                                    real_key = res.getString("key");
                                    uploadSucessHandle(real_key, uploadType);
                                    Log.d(TAG, "real_key and log: " + log);
                                } else {
                                    Log.d(TAG, "the key not found: " + log);
                                }
                            } catch (JSONException e) {
                                Log.d(TAG, "解析失败: " + e.getMessage());
                                Log.d(TAG, "解析失败log: " + log);
                            }
                        } else {
                            log += "upload fail";
                        }
                    }
                }, null);
    }

    protected String getUploadToken() {
        String temp = this.uploadToken;
        this.uploadToken = null;
        return temp;
    }

    protected void uploadSucessHandle(String key, UPLOAD_TYPE uploadType) {
        toast.setText("handle(string key):" + key);
        toast.show();
    }

    // 是否开始播放
    Boolean is_start = false;

    protected void play(String path) {

        if (path != "") {
            if (!is_start) {
                MediaPlayer player = new MediaPlayer();
                try {
                    player.setDataSource(path);
                    player.prepare();
                    player.start();
                    is_start = true;
                    toast.setText("已播放");
                } catch (Exception e) {
                    toast.setText("play exception：" + e.getMessage());
                }
                player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        is_start = false;
                    }
                });
            } else {
                toast.setText("请等待当前语音消息播放完");
            }
        } else {
            toast.setText("播放地址为空");
        }
        toast.show();
    }


    // 动态获取权限
    String[] permissions = new String[]{
            Manifest.permission.CAMERA,
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
    };
    List<String> mPermissionList = new ArrayList<>();

    // private ImageView welcomeImg = null;
    protected static final int PERMISSION_REQUEST = 1;

    protected void checkPermission() {
        mPermissionList.clear();

        //判断哪些权限未授予
        for (int i = 0; i < permissions.length; i++) {
            if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
                mPermissionList.add(permissions[i]);
            }
        }
        /**
         * 判断是否为空
         */
        if (mPermissionList.isEmpty()) {//未授予的权限为空，表示都授予了
//            toast.setText("全部权限已授权");
//            toast.show();
        } else {
            //请求权限方法
            String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]);//将List转为数组
            ActivityCompat.requestPermissions(BaseActivity.this, permissions, PERMISSION_REQUEST);
        }
    }


    // 录制音频
    protected MediaRecorder mr = null;

    protected String soundName = null;

    protected String soundPath = null;

    protected void startRecord() {
        if (mr == null) {

            File dir = getDir("sounds");
            // 文件名
            String file_name = System.currentTimeMillis() + ".amr";
            soundName = file_name;

            // 文件路径
            String path = dir.getPath() + "/" + file_name;
            soundPath = path;
            toast.setText("音频保存路径：" + path);
            toast.show();

            File soundFile = new File(dir, file_name);
            if (!soundFile.exists()) {
                try {
                    soundFile.createNewFile();
                } catch (IOException e) {
                    toast.setText("soundFile.createNewFile：" + e.getMessage());
                    toast.show();
                    e.printStackTrace();
                }

            }
            mr = new MediaRecorder();
            mr.setAudioSource(MediaRecorder.AudioSource.MIC);  //音频输入源
            mr.setOutputFormat(MediaRecorder.OutputFormat.AMR_WB);   //设置输出格式
            mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB);   //设置编码格式
            mr.setOutputFile(soundFile.getAbsolutePath());
            try {
                mr.prepare();
                mr.start();  //开始录制
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    // 获取目录，不存在则创建
    protected File getDir(String child) {
        File dir = new File(Environment.getExternalStorageDirectory(), "liqi_" + child);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dir;
    }

    // 停止录制，资源释放
    protected void stopRecord() {
        if (mr != null) {
            mr.stop();
            mr.release();
            mr = null;
        }
    }

    public Uri outputFileUri;
    // 拍照回传码
    public final static int CAMERA_REQUEST_CODE = 0;
    // 相册选择回传吗
    public final static int GALLERY_REQUEST_CODE = 1;

    // 拍照
    protected void startPhoto() {
        File file = createImageFile();
        outputFileUri = Uri.fromFile(file);
        Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        startActivityForResult(captureIntent, CAMERA_REQUEST_CODE);
    }

    // 相册选择
    protected void openPhotos() {
        Intent intent;
        if (android.os.Build.VERSION.SDK_INT < 19) {
            intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.setType("image/*");
        } else {
            intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        }
//        Intent intent = new Intent(Intent.ACTION_PICK, null);
        // 如果限制上传到服务器的图片类型时可以直接写如："image/jpeg 、 image/png等的类型" 所有类型则写 "image/*"
//        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/jpeg");
        startActivityForResult(intent, GALLERY_REQUEST_CODE);
    }

    //    Android 7.0调用系统拍照崩溃，exposed beyond app through ClipData.Item.getUri()
    protected void initPicture() {
        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());
        builder.detectFileUriExposure();
    }

    protected File createImageFile() {
        // Create an image file name
        String imageFileName = "JPEG" + System.currentTimeMillis();
        try {
            File image = File.createTempFile(imageFileName,  /* prefix */
                    ".jpg",         /* suffix */
                    getDir("photos")      /* directory */);
            return image;
        } catch (IOException e) {
            //do noting
            return null;
        }
    }

    // 拍照，选择相册 回调函数

    public Boolean isQC = true; // 是否压缩图片（默认压缩）

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode != RESULT_OK) {
            Log.d(TAG, "canceled or other exception!");
            return;
        }
        String path = null;

        switch (requestCode) {
            // 拍照
            case CAMERA_REQUEST_CODE:
                Log.d(TAG, "requestCode : 0");
                //TODO:Use the Uri
//                Intent intent = new Intent(ChatActivity.this, ChatActivity.class);
//                intent.setData(outputFileUri);
//                startActivity(intent);
                path = outputFileUri.getPath();
                break;
            // 选择相册
            case GALLERY_REQUEST_CODE:
                Log.d(TAG, "requestCode : 1");
                Uri dataUri = data.getData();
                path = getImagePath(dataUri);
                break;
        }

        Log.d(TAG, "原图片路径：" + path);

        if (path != null) {
            if (isQC) {
                // 压缩图片
                Bitmap bmp = getBitmap(new File(path));
                File qcImg = new File(getDir("photos"), System.currentTimeMillis() + "_qc.jpg");
                qualityCompress(bmp, qcImg);
                path = qcImg.getAbsolutePath();
                Log.d(TAG, "图片压缩后路径：" + path);
            }

            // 后续处理
            onPictureHandle(path);
        }
    }

    protected void onPictureHandle(String path) {
        Log.d(TAG, "onPictureHandle get param: " + path);
    }

    /**
     * 质量压缩
     * 设置bitmap options属性，降低图片的质量，像素不会减少
     * 第一个参数为需要压缩的bitmap图片对象，第二个参数为压缩后图片保存的位置
     * 设置options 属性0-100，来实现压缩（因为png是无损压缩，所以该属性对png是无效的）
     *
     * @param bmp
     * @param file
     */
    public static void qualityCompress(Bitmap bmp, File file) {
        // 0-100 100为不压缩
        int quality = 30;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // 把压缩后的数据存放到baos中
        bmp.compress(Bitmap.CompressFormat.JPEG, quality, baos);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Bitmap getBitmap(File file) {
        Bitmap bmp = null;
        try {
            if (android.os.Build.VERSION.SDK_INT >= 29) {
                // To handle deprication use
                bmp = ImageDecoder.decodeBitmap(ImageDecoder.createSource(file));
            } else {
                // Use older version
                Uri uri = Uri.fromFile(file);
                bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bmp;
    }

    // 获取图片真实地址
    protected String getImagePath(Uri uri) {
        return getImagePath(uri, null);
    }

    protected String getImagePath(Uri uri, String selection) {
        String path = null;
        Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }

            cursor.close();
        }
        return path;
    }

    // 下载图片到本地
    public void downloadImg(String url, final HashMap param) {
        Log.d(TAG, "downloadImg: ");
        Request request = new Request.Builder().url(url).build();
        new OkHttpClient().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: 下载失败" + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    Log.d(TAG, "onResponse: 下载成功");
                    writeFile(response, param);
                }
            }
        });
    }

    protected void writeFile(Response response, HashMap param) {

        InputStream is = null;
        FileOutputStream os = null;
        String path = null;

        is = response.body().byteStream();
        File dir = getDir("temp");
        String file_name = System.currentTimeMillis() + ".jpg";
        path = dir.getPath() + "/" + file_name;
        File file = new File(dir, file_name);
        try {
            os = new FileOutputStream(file);
            byte[] bytes = new byte[1024];
            int len = 0;
            //获取下载的文件的大小
            while ((len = is.read(bytes)) != -1) {
                os.write(bytes, 0, len);
            }
            Log.d(TAG, "onResponse: " + path);

            // 后续操作
            downloadImageHandler(path, param);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 下载图片完成后后续操作
    public void downloadImageHandler(String path, HashMap param) {
        Log.d(TAG, "downloadImageHandler: then...");
    }
}